package com.epi.two;

import java.text.Collator;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.*;
import java.util.concurrent.atomic.*;

/**
 * @author dxy
 * @version 1.0
 * @see <a href="https://www.w3.org/International/articles/language-tags/">W3C语言标签</a>
 */
public class LocaleDemo {
    public static void main(String[] args) {
//        availableLocalesDemo();
//        languageDemo();
//        numFormatterDemo();
//        currencyDemo();
//        dateDemo();
//        collatorDemo();
//        messageFormatDemo();
//        resourceBundleDemo();
    }

    private static void resourceBundleDemo() {
        /***
         * 查找顺序
         * baseName_currentLocaleLanguage_currentLocaleCountry
         * baseName_currentLocaleLanguage
         * baseName_currentLocaleLanguage_defaultLocaleCountry
         * baseName_defaultLocaleLanguage
         * baseName
         */
        ResourceBundle rb = ResourceBundle.getBundle("localeDir.bn", new Locale("en", "US"));
        Enumeration<String> keys = rb.getKeys();
        keys.asIterator().forEachRemaining(key -> System.out.println(key+"="+rb.getString(key)));
    }

    private static void messageFormatDemo() {
        String message = "On {2,date,long}, {0} destroyed {1,choice,0#no houses|1#one house|2#{1} houses}  and caused {3,number,currency} of damage.";
        String formatted = MessageFormat.format(message, "an earthquake", 0.5, Date.from(Instant.now()), 2E8);
        System.out.println(formatted);
    }

    private static void collatorDemo() {
        String[] words = {
            "äbc", "abc", "åbc", "ábč", "ábz", "Åbc", "ábz", "Æbc", "ÆbD", "Äbc", "abcd"
        };

        sortAndPrint("🇺🇸 Locale.US", words, Locale.US);
        sortAndPrint("🇩🇪 Locale.GERMANY", words, Locale.GERMANY);
        sortAndPrint("🇸🇪 Locale(" + "\"sv\", \"SE\")", words, new Locale("sv", "SE")); // 瑞典语
        sortAndPrint("🇪🇸 Locale(" + "\"es\", \"ES\")", words, new Locale("es", "ES")); // 西班牙语
        sortAndPrint("🇩🇰 Locale(" + "\"da\", \"DK\")", words, new Locale("da", "DK")); // 丹麦语
    }

    private static void sortAndPrint(String label, String[] data, Locale locale) {
        System.out.println("\n== " + label + " ==");
        String[] copy = Arrays.copyOf(data, data.length);
        Arrays.sort(copy, Collator.getInstance(locale));
        for (String s : copy) {
            System.out.println(s);
        }
    }

    private static void dateDemo() {
        // 日期和语言绑定，货币和国家绑定
        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.GERMAN);
        String formatted = formatter.format(ZonedDateTime.now());
        System.out.println(formatted);
    }

    private static void currencyDemo() {
        double amount = 1234.56;
        // 1. 德国 Locale 的货币格式器
        NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.GERMANY);
        // 2. 设置货币为美元 只是把€符号换成了$
        nf.setCurrency(Currency.getInstance("USD"));
        // 3. 格式化金额
        System.out.println(nf.format(amount));
    }

    private static void numFormatterDemo() {
        double number = 1234567.89;
        double percent = 0.8532;

        // 定义三个 Locale
        Locale[] locales = {
            Locale.US,
            Locale.GERMANY,
            Locale.CHINA
        };

        for (Locale locale : locales) {
            System.out.println("===== Locale: " + locale.getDisplayName() + " =====");

            // 数字格式
            NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
            System.out.println("数字格式:     " + numberFormat.format(number));

            // 货币格式
            NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(locale);
            System.out.println("货币格式:     " + currencyFormat.format(number));

            // 百分比格式
            NumberFormat percentFormat = NumberFormat.getPercentInstance(locale);
            percentFormat.setMinimumFractionDigits(2); // 保留两位小数
            System.out.println("百分比格式:   " + percentFormat.format(percent));

            System.out.println();
        }
    }

    private static void languageDemo() {
        var loc = new Locale("de", "CH");
        System.out.println(loc.getDisplayName(Locale.JAPANESE));
        String s = "QUIT Ä, Ö, Ü A É";
        System.out.println(s.toLowerCase());
        System.out.println(s.toLowerCase(Locale.forLanguageTag("tr")));
        System.out.println(s.toLowerCase(Locale.forLanguageTag("el")));
    }

    private static void availableLocalesDemo() {
        AtomicInteger idx = new AtomicInteger();

        System.out.println("===========Locales==========");
        idx.set(0);
        Arrays.stream(Locale.getAvailableLocales())
            .forEach(locale -> System.out.println(idx.getAndIncrement() + " " + locale));

        System.out.println("===========Languages==========");  //一般小写
        idx.set(0);
        Arrays.stream(Locale.getISOLanguages()).sorted()
            .forEach(language -> System.out.println(idx.getAndIncrement() + " " + language));

        System.out.println("===========Countries=========="); //一般大写
        idx.set(0);
        Arrays.stream(Locale.getISOCountries()).sorted()
            .forEach(country -> System.out.println(idx.getAndIncrement() + " " + country));

        System.out.println("===========Example==========");
        Locale locale = Locale.getAvailableLocales()[240];  //zh_HK_#Hans
        System.out.println("zh_HK_#Hans  " + locale.getDisplayCountry() + " " + locale.getDisplayLanguage()); // 语言+位置+脚本
        System.out.println(Locale.CHINA + Locale.CHINA.getDisplayCountry() + " " + Locale.CHINA.getDisplayLanguage()); //语言+位置
        System.out.println(Locale.CHINESE + Locale.CHINESE.getDisplayCountry() + " " + Locale.CHINESE.getDisplayLanguage()); // 语言
    }
}
